package compiler.nonterminals;

import java.util.LinkedList;
import java.util.List;

import compiler.HowlToken;
import compiler.HowlType;
import compiler.TokenReader;
import compiler.exceptions.HowlParserException;
import compiler.terminals.DataProvider;
import compiler.terminals.DataValue;
import compiler.terminals.FeedName;

/**
 * This class represents insert statements, as in:
 * 
 * insert FeedName DataProvider (Name Value)+
 * 
 * @author Sarah Mount <s.mount@wlv.ac.uk>
 * @version 16 Dec 2009
 * @see compiler.terminals.FeedName
 * @see compiler.terminals.DataProvider
 * @see compiler.terminals.DataValue
 */
public class InsertStmt extends HowlToken {
	private FeedName feedname;
	private DataProvider dataprovider;
	private List<DataValue> datavalues;

	public InsertStmt(TokenReader tokenReader) {
		super(tokenReader);
	}

	@Override
	public String codeGenerate() {
		String query = "INSERT INTO " + this.feedname.codeGenerate()
				+ " VALUES (";
		// TODO: Use iterators sensibly here.
		String values = "";
		Object[] valueArray = this.datavalues.toArray();
		for (int i = 0; i < valueArray.length - 1; i++) {
			values += this.dataprovider.codeGenerate() + "."
					+ ((DataValue) valueArray[i]).codeGenerate() + ", ";
		}
		// No comma after last value.
		values += this.dataprovider.codeGenerate() + "."
				+ valueArray[valueArray.length - 1];
		return query + values + ");";
	}

	@Override
	public HowlToken parse() throws HowlParserException {
		String command = this.tokenReader.consumeToken();
		if (!"insert".equals(command))
			throw new HowlParserException(this.tokenReader.getStatement(),
					this.tokenReader.getCharNo());
		this.feedname = (FeedName) new FeedName(this.tokenReader).parse();
		this.dataprovider = (DataProvider) new DataProvider(this.tokenReader)
				.parse();
		this.datavalues = new LinkedList<DataValue>();
		while (!this.tokenReader.hasEndStmt()
				&& this.tokenReader.hasMoreTokens()) {
			DataValue dv = (DataValue) new DataValue(this.tokenReader).parse();
			if (dv != null) {
				this.datavalues.add(dv);
			}
		}
		return this;
	}

	@Override
	public String toString() {
		String obj = "insert " + this.feedname.toString() + " "
				+ this.dataprovider.toString();
		for (DataValue dv : this.datavalues) {
			obj += " " + dv.toString();
		}
		return obj + ";";
	}

	/**
	 * @return the feedname
	 */
	public FeedName getFeedname() {
		return feedname;
	}

	/**
	 * @param feedname the feedname to set
	 */
	public void setFeedname(FeedName feedname) {
		this.feedname = feedname;
	}

	/**
	 * @return the dataprovider
	 */
	public DataProvider getDataprovider() {
		return dataprovider;
	}

	/**
	 * @param dataprovider the dataprovider to set
	 */
	public void setDataprovider(DataProvider dataprovider) {
		this.dataprovider = dataprovider;
	}

	/**
	 * @return the datavalues
	 */
	public List<DataValue> getDatavalues() {
		return datavalues;
	}

	/**
	 * @param datavalues the datavalues to set
	 */
	public void setDatavalues(List<DataValue> datavalues) {
		this.datavalues = datavalues;
	}


}